package com.petvc.tv

import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import java.io.IOException
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeUnit.NANOSECONDS

class NetworkUtils {
    companion object {
        private const val JSON_MEDIA_TYPE = "application/json; charset=utf-8"
        
        // 创建OkHttpClient实例
        private val client = OkHttpClient.Builder()
            .connectTimeout(ApiConfig.HttpConfig.CONNECT_TIMEOUT_SECONDS, TimeUnit.SECONDS)
            .readTimeout(ApiConfig.HttpConfig.READ_TIMEOUT_SECONDS, TimeUnit.SECONDS)
            .writeTimeout(ApiConfig.HttpConfig.WRITE_TIMEOUT_SECONDS, TimeUnit.SECONDS)
            .build()
        
        /**
         * 检查网络连接状态
         */
        fun isNetworkAvailable(context: Context): Boolean {
            val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            val network = connectivityManager.activeNetwork ?: return false
            val activeNetwork = connectivityManager.getNetworkCapabilities(network) ?: return false
            
            val isAvailable = when {
                activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
                activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
                activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
                else -> false
            }
            
            LogUtils.logNetwork("网络连接状态检查: 可用=$isAvailable")
            return isAvailable
        }
        
        /**
         * 发送POST请求
         */
        suspend fun postRequest(
            url: String,
            jsonData: String,
            headers: Map<String, String> = emptyMap()
        ): ApiResponse = withContext(Dispatchers.IO) {
            val startTime = System.nanoTime()
            LogUtils.logNetwork("开始POST请求: $url")
            LogUtils.logNetworkRequest(url, "POST", headers, jsonData)
            
            try {
                val requestBody = jsonData.toRequestBody(JSON_MEDIA_TYPE.toMediaType())
                
                val requestBuilder = Request.Builder()
                    .url(url)
                    .post(requestBody)
                    .addHeader("Content-Type", JSON_MEDIA_TYPE)
                
                // 添加自定义请求头
                headers.forEach { (key, value) ->
                    requestBuilder.addHeader(key, value)
                }
                
                val request = requestBuilder.build()
                LogUtils.logNetwork("执行请求...")
                val response = client.newCall(request).execute()
                
                val responseBody = response.body?.string() ?: ""
                val statusCode = response.code
                val responseHeaders = response.headers.toMap()
                
                LogUtils.logNetworkResponse(url, statusCode, responseBody, responseHeaders)
                
                val duration = NANOSECONDS.toMillis(System.nanoTime() - startTime)
                LogUtils.logPerformance("POST请求", duration)
                
                // 确保响应被关闭
                response.close()
                
                return@withContext handleResponse(statusCode, responseBody, responseHeaders)
            } catch (e: Exception) {
                val duration = NANOSECONDS.toMillis(System.nanoTime() - startTime)
                
                // 检查是否是网络安全策略错误
                if (e.message?.contains("CLEARTEXT") == true || e.message?.contains("network security policy") == true) {
                    LogUtils.logSecurityError("明文通信被阻止: ${e.message}", e)
                    LogUtils.logNetworkError(url, "网络安全策略阻止了HTTP请求", e)
                } else {
                    LogUtils.logNetworkError(url, "请求异常: ${e.message}", e)
                }
                
                LogUtils.logPerformance("POST请求(失败)", duration)
                
                return@withContext ApiResponse(
                    success = false,
                    message = "网络请求失败: ${e.message}",
                    data = null,
                    statusCode = -1
                )
            }
        }
        
        /**
         * 发送GET请求
         */
        suspend fun getRequest(
            url: String,
            headers: Map<String, String> = emptyMap()
        ): ApiResponse = withContext(Dispatchers.IO) {
            val startTime = System.nanoTime()
            LogUtils.logNetwork("开始GET请求: $url")
            LogUtils.logNetworkRequest(url, "GET", headers)
            
            try {
                val requestBuilder = Request.Builder()
                    .url(url)
                    .get()
                
                // 添加自定义请求头
                headers.forEach { (key, value) ->
                    requestBuilder.addHeader(key, value)
                }
                
                val request = requestBuilder.build()
                LogUtils.logNetwork("执行请求...")
                val response = client.newCall(request).execute()
                
                val responseBody = response.body?.string() ?: ""
                val statusCode = response.code
                val responseHeaders = response.headers.toMap()
                
                LogUtils.logNetworkResponse(url, statusCode, responseBody, responseHeaders)
                
                val duration = NANOSECONDS.toMillis(System.nanoTime() - startTime)
                LogUtils.logPerformance("GET请求", duration)
                
                // 确保响应被关闭
                response.close()
                
                return@withContext handleResponse(statusCode, responseBody, responseHeaders)
            } catch (e: Exception) {
                val duration = NANOSECONDS.toMillis(System.nanoTime() - startTime)
                
                // 检查是否是网络安全策略错误
                if (e.message?.contains("CLEARTEXT") == true || e.message?.contains("network security policy") == true) {
                    LogUtils.logSecurityError("明文通信被阻止: ${e.message}", e)
                    LogUtils.logNetworkError(url, "网络安全策略阻止了HTTP请求", e)
                } else {
                    LogUtils.logNetworkError(url, "请求异常: ${e.message}", e)
                }
                
                LogUtils.logPerformance("GET请求(失败)", duration)
                
                return@withContext ApiResponse(
                    success = false,
                    message = "网络请求失败: ${e.message}",
                    data = null,
                    statusCode = -1
                )
            }
        }
        
        /**
         * 处理响应
         */
        private fun handleResponse(statusCode: Int, responseBody: String, responseHeaders: Map<String, String>? = null): ApiResponse {
            return try {
                LogUtils.logNetwork("处理响应: 状态码=$statusCode, 响应体长度=${responseBody.length}")
                
                when {
                    statusCode in 200..299 -> {
                        try {
                            val jsonObject = JSONObject(responseBody)
                            val success = jsonObject.optBoolean("success", true)
                            val message = jsonObject.optString("message", "请求成功")
                            val data = jsonObject.opt("data")
                            
                            LogUtils.logNetwork("响应解析成功: success=$success, message=$message")
                            
                            ApiResponse(
                                success = success,
                                message = message,
                                data = data,
                                statusCode = statusCode
                            )
                        } catch (e: Exception) {
                            LogUtils.logNetwork("JSON解析失败，使用原始响应: ${e.message}")
                            ApiResponse(
                                success = true,
                                message = "请求成功",
                                data = responseBody,
                                statusCode = statusCode
                            )
                        }
                    }
                    statusCode == ApiConfig.StatusCode.UNAUTHORIZED -> {
                        LogUtils.logNetwork("认证失败: 状态码=$statusCode")
                        ApiResponse(
                            success = false,
                            message = "认证失败，请重新登录",
                            data = null,
                            statusCode = statusCode
                        )
                    }
                    statusCode == ApiConfig.StatusCode.BAD_REQUEST -> {
                        LogUtils.logNetwork("请求参数错误: 状态码=$statusCode")
                        ApiResponse(
                            success = false,
                            message = "请求参数错误",
                            data = null,
                            statusCode = statusCode
                        )
                    }
                    statusCode == ApiConfig.StatusCode.NOT_FOUND -> {
                        LogUtils.logNetwork("资源不存在: 状态码=$statusCode")
                        ApiResponse(
                            success = false,
                            message = "请求的资源不存在",
                            data = null,
                            statusCode = statusCode
                        )
                    }
                    statusCode >= 500 -> {
                        LogUtils.logNetwork("服务器错误: 状态码=$statusCode")
                        ApiResponse(
                            success = false,
                            message = "服务器内部错误",
                            data = null,
                            statusCode = statusCode
                        )
                    }
                    else -> {
                        LogUtils.logNetwork("其他错误: 状态码=$statusCode")
                        ApiResponse(
                            success = false,
                            message = "请求失败 (状态码: $statusCode)",
                            data = null,
                            statusCode = statusCode
                        )
                    }
                }
            } catch (e: Exception) {
                LogUtils.logNetworkError("", "响应解析错误: ${e.message}", e)
                ApiResponse(
                    success = false,
                    message = "响应解析错误: ${e.message}",
                    data = null,
                    statusCode = -1
                )
            }
        }
    }
}

/**
 * API响应数据类
 */
data class ApiResponse(
    val success: Boolean,
    val message: String,
    val data: Any?,
    val statusCode: Int
) 